package com.dikeleakagedetection.myapplication.ui.ble

import android.bluetooth.BluetoothGatt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.clj.fastble.BleManager
import com.clj.fastble.callback.BleGattCallback
import com.clj.fastble.callback.BleScanCallback
import com.clj.fastble.data.BleDevice
import com.clj.fastble.exception.BleException
import com.clj.fastble.scan.BleScanRuleConfig
import com.dikeleakagedetection.myapplication.MainActivity
import com.dikeleakagedetection.myapplication.DikeLeakageDetectionApp
import com.dikeleakagedetection.myapplication.R
import com.dikeleakagedetection.myapplication.databinding.FragBleMainBinding
import com.dikeleakagedetection.myapplication.utils.showToast

class BleFragment : Fragment() {

    companion object {
        fun newInstance() = BleFragment()
    }

    private lateinit var binding: FragBleMainBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragBleMainBinding.inflate(inflater, container, false)
        val view = binding.root

        BleManager.getInstance().init(DikeLeakageDetectionApp.instance())

        val mDeviceAdapter = DeviceAdapter(view.context, ArrayList())

        //“开始扫描”按键
        binding.btnScanFragBleMain.setOnClickListener {
            when (binding.btnScanFragBleMain.text) {
                getString(R.string.start_scan) -> startScan(mDeviceAdapter)
                getString(R.string.stop_scan) -> BleManager.getInstance().cancelScan()
            }
        }

        //设备列表(rv_device)
        val linearLayoutManager = LinearLayoutManager(context)
        linearLayoutManager.orientation = RecyclerView.VERTICAL
        binding.rvDevicesFragBleMain.layoutManager = linearLayoutManager

        mDeviceAdapter.setOnDeviceClickListener(object : DeviceAdapter.OnDeviceClickListener {
            override fun onConnect(bleDevice: BleDevice?) {
                if (!BleManager.getInstance().isConnected(bleDevice)) {
                    BleManager.getInstance().cancelScan()
                    connect(bleDevice, mDeviceAdapter)
                }
            }

            override fun onDisConnect(bleDevice: BleDevice?) {
                if (BleManager.getInstance().isConnected(bleDevice)) {
                    BleManager.getInstance().disconnect(bleDevice)
                    DikeLeakageDetectionApp.currentBleDevice.bleDevice = null
                    DikeLeakageDetectionApp.currentBleDevice.characteristic = null
                }
            }

            //要改成replaceFragment
            override fun onDetail(bleDevice: BleDevice?) {
                if (BleManager.getInstance().isConnected(bleDevice)) {
                    val serviceFragment: ServiceFragment =
                        ServiceFragment.newInstance(bleDevice!!)
                    (activity as MainActivity?)!!.replaceFragment(serviceFragment)
                }
            }
        })

        binding.rvDevicesFragBleMain.adapter = mDeviceAdapter
        binding.rvDevicesFragBleMain.addItemDecoration(
            DividerItemDecoration(
                context,
                DividerItemDecoration.VERTICAL
            )
        )

        //配置蓝牙参数
        BleManager.getInstance()
            .enableLog(false) //打开日志
            .setReConnectCount(1, 5000) //重连次数和重连间隔
            .setSplitWriteNum(20) //分包发送，每一包数据长度
            .setConnectOverTime(10000)
            .operateTimeout = 5000 //设置readRssi、setMtu、write、read、notify、indicate的超时时间（毫秒），默认5秒
        return view
    }

    private fun connect(bleDevice: BleDevice?, mDeviceAdapter: DeviceAdapter) {
        BleManager.getInstance().connect(bleDevice, object : BleGattCallback() {
            override fun onStartConnect() {}
            override fun onConnectFail(bleDevice: BleDevice, exception: BleException) {
                binding.btnScanFragBleMain.text = getString(R.string.start_scan)
                R.string.connect_fail.showToast()

            }

            override fun onConnectSuccess(bleDevice: BleDevice, gatt: BluetoothGatt, status: Int) {
               /* BleManager.getInstance().cancelScan()
                binding.btnScan.text = "开始扫描"
                mDeviceAdapter.clearScanDevice()*/
                mDeviceAdapter.clear()
                mDeviceAdapter.addDevice(bleDevice)
                mDeviceAdapter.notifyDataSetChanged()
                DikeLeakageDetectionApp.currentBleDevice.bleDevice = bleDevice
                DikeLeakageDetectionApp.currentBleDevice.characteristic = BleManager.getInstance().getBluetoothGatt(bleDevice).services[2].characteristics[1]
            }

            override fun onDisConnected(
                isActiveDisConnected: Boolean,
                bleDevice: BleDevice,
                gatt: BluetoothGatt,
                status: Int
            ) {
                mDeviceAdapter.removeDevice(bleDevice)
                mDeviceAdapter.notifyDataSetChanged()
                if (isActiveDisConnected) {
                    R.string.active_disconnected.showToast()
                } else {
                    R.string.disconnected.showToast()
                    //ObserverManager.getInstance().notifyObserver(bleDevice);
                }
            }
        })
    }

    private fun startScan(mDeviceAdapter: DeviceAdapter) {
        //配置扫描规则
        val scanRuleConfig = BleScanRuleConfig.Builder()
            .setServiceUuids(null) // 只扫描指定的服务的设备，可选
            //.setDeviceName(true, "Nordic_UART")   // 只扫描指定广播名的设备，可选
            .setDeviceMac("") // 只扫描指定mac的设备，可选
            .setAutoConnect(false) // 连接时的autoConnect参数，可选，默认false
            .setScanTimeOut(10000) // 扫描超时时间，可选，默认10秒
            .build()
        BleManager.getInstance().initScanRule(scanRuleConfig)

        // 开始扫描
        BleManager.getInstance().scan(object : BleScanCallback() {
            override fun onScanStarted(success: Boolean) {
                mDeviceAdapter.clear()
                mDeviceAdapter.notifyDataSetChanged()
                binding.btnScanFragBleMain.text = getString(R.string.stop_scan)
            }

            override fun onScanning(bleDevice: BleDevice) {
                mDeviceAdapter.addDevice(bleDevice)
                mDeviceAdapter.notifyDataSetChanged()
            }

            override fun onScanFinished(scanResultList: List<BleDevice>) {
                binding.btnScanFragBleMain.text = getString(R.string.start_scan)
            }
        })
    }


}